package com.base.designpattern.facade;

/**
 *  使用门面模式
 */
public class FacadePatternDemo {

	public static void main(String[] args) {
		// 假设是子系统2
		SystemFacade facade = new SystemFacade();
		facade.exucute();

		// 好处1：子系统2不需要care太多的模块，只要care一个门面类的接口就可以了
		// 好处2：如果多个地方都要调用这段逻辑，那么如果这个逻辑变了，只需要在门面类一个地方修改就可以了
		/**
		 * 外观模式其实很简单，就是说，假设我们有一个系统A吧，自己内部有多个代码组件，
		 * 每个代码组件都可以实现一些功能。此时如果别的系统B要调用系统A实现某个功能，此时一种方法是，
		 * 系统B调用系统A的多个代码组件的方法，最终实现一个功能。另外一个选择，就是系统A里提供一个Facade类，
		 * 系统B不需要care系统A内部有多少个代码组件，直接调用系统A的一个facade类的一个方法即可。
		 *
		 * 就是说，大家可以想象一下，比如说service就是一个经典的门面模式
		 *
		 * 如果一个子系统里有多个DAO组件，然后如果别的子系统要实现一段业务逻辑，
		 * 需要使用这个子系统的多个DAO组件，那就会导致别的子系统代码会很乱，
		 * 需要care这个子系统很多DAO组件的实现。
		 * 但是这个组件可以基于多个DAO组件封装出来一个service接口，
		 * 然后别的系统就针对一个service接口开发即可。这个service不就是一个典型的门面吗？
		 *
		 * 这个模式在我们的电商系统里可以大量使用，就是用facade包装每个子系统内部的大量代码组件，对外暴露统一简单的接口
		 */
	}

	/**
	 * 子系统1的门面类
	 * @author zhonghuashishan
	 *
	 */
	public static class SystemFacade {

		public void exucute() {
			// 子系统1，封装了自己的多个模块，ABC，基于自己多个模块的功能，对外统一暴露出去一个功能
			ModuleA moduleA = new ModuleA();
			ModuleB moduleB = new ModuleB();
			ModuleC moduleC = new ModuleC();

			moduleA.execute();
			moduleB.execute();
			moduleC.execute();
			System.out.println("新增的一段逻辑");
		}

	}

	public static class ModuleA {

		public void execute() {
			System.out.println("子系统1的模块A的功能");
		}

	}

	public static class ModuleB {

		public void execute() {
			System.out.println("子系统1的模块B的功能");
		}

	}

	public static class ModuleC {

		public void execute() {
			System.out.println("子系统1的模块C的功能");
		}

	}

}
